<template>
  <div class="main flex-column-left-between width-all">
    <!------------------------------------------ 顶部 ------------------------------------------------------->

    <div class="top bg-white">
      <div class="bold mgb10">故障数量概览</div>
      <div class="gap30 flex-row-center-between">
        <OverviewItem :data="state.rawGraphData.monthFault" type="月" />
        <OverviewItem :data="state.rawGraphData.quarterFault" type="季" />
        <OverviewItem :data="state.rawGraphData.yearFault" type="年" />
      </div>
    </div>

    <!------------------------------------------ 月份图 ------------------------------------------------------->

    <div class="flex1 flex-row-center-between bg-white">
      <div v-show="state.rawGraphData?.monthTrend?.length" class="flex1 flex-column height-all">
        <div class="flex-row-center-left">
          <div class="bold">故障流量趋势 月度</div>
          <div class="mgl30 flex-row-center-left">
            <SelectVue style="width: 150px" v-model="state.monthQuery.startTime" :option-list="monthRange" @change="onMonthChange" :clearable="false" />
            <span class="grey-text mgl5 mgr5">至</span>
            <SelectVue style="width: 150px" v-model="state.monthQuery.endTime" :option-list="monthRange" @change="onMonthChange" :clearable="false" />
          </div>
        </div>
        <div id="graph-month" class="graph flex1 width-all height-all"></div>
      </div>

      <GraphDesc v-show="state.rawGraphData?.monthTrend?.length" :month-graph-data="state.monthGraphData" />

      <empty v-if="!state.rawGraphData?.monthTrend?.length" style="margin: auto" />
    </div>

    <!------------------------------------------ 季度图 ------------------------------------------------------->

    <div class="flex1 flex-row-center-between bg-white">
      <div v-show="state.rawGraphData?.quarterTrend?.length" class="flex1 flex-column height-all">
        <div class="flex-row-center-left">
          <div class="bold">故障流量趋势 季度</div>
          <div class="mgl30 flex-row-center-left">
            <SelectVue style="width: 150px" v-model="state.quarterQuery.startTime" :option-list="quarterRange" @change="onQuarterChange" :clearable="false" />
            <span class="grey-text mgl5 mgr5">至</span>
            <SelectVue style="width: 150px" v-model="state.quarterQuery.endTime" :option-list="quarterRange" @change="onQuarterChange" :clearable="false" />
          </div>
        </div>
        <div id="graph-quarter" class="graph flex1 width-all height-all"></div>
      </div>

      <GraphDesc v-show="state.rawGraphData?.quarterTrend?.length" :month-graph-data="state.quarterGraphData" />

      <empty v-if="!state.rawGraphData?.quarterTrend?.length" style="margin: auto" />
    </div>
  </div>
</template>

<script setup lang="ts">
  import { reactive, onMounted, onUnmounted, nextTick } from 'vue'
  import * as echarts from 'echarts'
  import type { ECharts } from 'echarts'
  import { max, min } from 'xe-utils'
  import SelectVue from '@/components/select'
  import GraphDesc from './cpns/graph-desc.vue'
  import OverviewItem from './cpns/overview-item.vue'
  import request from '@/service'
  import { Ui } from '@/utils'
  import type { GraphDto, GraphData } from './config'
  import { setChartOptions } from './config'
  import empty from '@/components/empty/empty.vue'

  const initData = () => ({
    xAxis: [] as string[],
    seriesFaultCount: [] as number[],
    seriesMomRatio: [] as number[], // 环比
    seriesYoyBasis: [] as number[], // 同比
    maxFaultCountItem: {} as GraphData,
    minFaultCountItem: {} as GraphData,
    maxMomRatioItem: {} as GraphData,
    minMomRatioItem: {} as GraphData,
    maxYoyBasisItem: {} as GraphData,
    minYoyBasisItem: {} as GraphData,
    yAxisRightMax: 100,
    yAxisRightMin: 0
  })

  const state = reactive({
    rawGraphData: {} as GraphDto,
    monthGraphData: initData(),
    quarterGraphData: initData(),
    quarterQuery: {
      startTime: '',
      endTime: ''
    },
    monthQuery: {
      startTime: '',
      endTime: ''
    }
  })

  let monthRange: string[] = []
  let quarterRange: string[] = []

  let monthChart: ECharts
  let quarterChart: ECharts

  /**----------------------------methods----------------------------------------------------------------------- */

  const onMonthChange = () => {
    const r = (str: string) => str.replace('.', '')
    const { startTime, endTime } = state.monthQuery
    const list = state.rawGraphData.monthTrend.filter(item => r(item.dateString) >= r(startTime) && r(item.dateString) <= r(endTime))
    if (!list.length) return Ui.useMessage('warning', '月份间隔无效，请重新选择')
    mapGraphData(monthChart, list, 'monthGraphData')
  }

  const onQuarterChange = () => {
    const r = (str: string) => str.replace('.S', '')

    const { startTime, endTime } = state.quarterQuery
    const list = state.rawGraphData.quarterTrend.filter(item => {
      return r(item.dateString) >= r(startTime) && r(item.dateString) <= r(endTime)
    })
    if (!list.length) return Ui.useMessage('warning', '季度间隔无效，请重新选择')
    mapGraphData(quarterChart, list, 'quarterGraphData')
  }

  const resize = () => {
    monthChart.resize()
    quarterChart.resize()
  }

  const initGraph = () => {
    monthChart = echarts.init(document.getElementById('graph-month'))
    quarterChart = echarts.init(document.getElementById('graph-quarter'))

    window.addEventListener('resize', resize)
  }

  const setOptions = (echart: ECharts, key: 'monthGraphData' | 'quarterGraphData') => {
    const { xAxis, maxFaultCountItem, yAxisRightMax, yAxisRightMin, seriesFaultCount, seriesYoyBasis, seriesMomRatio } = state[key]
    setChartOptions(echart, xAxis, maxFaultCountItem?.dateCount, yAxisRightMax, yAxisRightMin, seriesFaultCount, seriesYoyBasis, seriesMomRatio)
  }

  const mapGraphData = (echart: ECharts, list: GraphData[], key: 'monthGraphData' | 'quarterGraphData') => {
    state[key].xAxis = list.map(item => item.dateString)
    state[key].seriesFaultCount = list.map(item => item.dateCount)
    state[key].seriesMomRatio = list.map(item => parseFloat(item.momRatio.replace('%', '')))
    state[key].seriesYoyBasis = list.map(item => parseFloat(item.yoyBasis.replace('%', '')))

    state[key].maxFaultCountItem = max(list, 'dateCount')
    state[key].minFaultCountItem = min(list, 'dateCount')

    state[key].maxMomRatioItem = max(list, item => parseFloat(item.momRatio.replace('%', ''))) as GraphData
    state[key].minMomRatioItem = min(list, item => parseFloat(item.momRatio.replace('%', ''))) as GraphData

    state[key].maxYoyBasisItem = max(list, item => parseFloat(item.yoyBasis.replace('%', ''))) as GraphData
    state[key].minYoyBasisItem = min(list, item => parseFloat(item.yoyBasis.replace('%', ''))) as GraphData

    const minMomRatio = parseFloat(state[key].minMomRatioItem?.momRatio.replace('%', ''))
    const minYoyBasis = parseFloat(state[key].minYoyBasisItem?.yoyBasis.replace('%', ''))

    const maxMomRatio = parseFloat(state[key].maxMomRatioItem?.momRatio.replace('%', ''))
    const maxYoyBasis = parseFloat(state[key].maxYoyBasisItem?.yoyBasis.replace('%', ''))

    state[key].yAxisRightMin = min([minMomRatio, minYoyBasis])
    //@ts-ignore
    state[key].yAxisRightMax = max([maxMomRatio, maxYoyBasis])

    setOptions(echart, key)
  }

  /**获取数据 */
  const getGraphData = () => {
    request.get<GraphDto>('/fault/getFaultAmount').then(res => {
      if (res.code !== 0) return Ui.useMessage('error', res.msg)
      state.rawGraphData = res.data
      const { monthTrend, quarterTrend } = res.data

      if (!monthTrend.length || !quarterTrend.length) return

      monthRange = monthTrend.map(item => item.dateString)
      quarterRange = quarterTrend.map(item => item.dateString)

      state.monthQuery.startTime = monthRange[0]
      state.monthQuery.endTime = monthRange.at(-1) as string

      state.quarterQuery.startTime = quarterRange[0]
      state.quarterQuery.endTime = quarterRange.at(-1) as string

      nextTick(() => {
        initGraph()

        // 月度
        mapGraphData(monthChart, monthTrend, 'monthGraphData')

        // 季度
        mapGraphData(quarterChart, quarterTrend, 'quarterGraphData')
      })
    })
  }

  /**----------------------------lifecycle----------------------------------------------------------------------- */

  onMounted(() => {
    getGraphData()
  })

  onUnmounted(() => {
    monthChart.dispose()
    quarterChart.dispose()
    window.removeEventListener('resize', resize)
  })
</script>

<style scoped lang="less">
  .main {
    background: #f2f6fc !important;
    gap: 16px !important;
    padding: 0;
    .bg-white {
      padding: 10px;
      background: #fff;
    }
  }
</style>
